"""
导入 HSP 示例数据脚本

功能：
- 从 JSON 文件读取晶体学点群数据
- 验证数据结构
- 使用 Beanie ODM 导入到 MongoDB 数据库

使用方法：
    python -m app.utils.import_sample_data
"""

import asyncio
import json
from pathlib import Path

from app.core.database import mongodb
from app.models import PointGroupDocument


def load_point_groups_from_json():
    """从 JSON 文件加载点群数据"""
    # 获取当前文件所在目录的父目录(app)，然后找到 data 目录
    current_dir = Path(__file__).parent.parent
    data_dir = current_dir / "data"
    datasets = [
        "crystallographic_point_groups.json",
        "non_crystallographic_point_groups.json",
    ]

    combined: list[dict] = []

    for filename in datasets:
        json_file = data_dir / filename
        if not json_file.exists():
            if "crystallographic" in filename:
                raise FileNotFoundError(f"找不到数据文件: {json_file}")
            # 非晶体数据缺失时记录提示但不阻塞主流程
            print(f"⚠️  可选数据文件缺失: {json_file}")
            continue

        with open(json_file, "r", encoding="utf-8") as f:
            data = json.load(f)

        if not isinstance(data, list):
            raise ValueError(f"数据文件格式错误，应为列表: {json_file}")

        combined.extend(data)

    print(f"✅ 加载了 {len(combined)} 个点群")

    return combined


async def import_point_groups():
    """导入点群数据到 MongoDB（使用 Beanie）"""
    # 初始化数据库
    print("🚀 正在初始化数据库...")
    await mongodb.initialize()

    # 从 JSON 文件加载数据
    print("📖 正在读取数据文件...")
    point_groups_data = load_point_groups_from_json()
    print(f"📖 读取到 {len(point_groups_data)} 个晶体学点群")

    # 清空现有数据（可选）
    print("🗑️  正在清空现有点群数据...")
    await PointGroupDocument.delete_all()
    print("✅ 已清空现有数据")

    # 将 JSON 数据转换为 PointGroupDocument 对象
    print("🔄 正在验证和转换数据...")
    point_groups = []
    for data in point_groups_data:
        try:
            # JSON 数据已经包含完整的字段（det、axis、angle、su2、irrep_matrices）
            # 由 merge_toweb_data.py 合并后生成，无需再次计算

            # 直接创建 PointGroupDocument 实例
            point_group = PointGroupDocument(**data)
            point_groups.append(point_group)
        except Exception as e:
            print(f"⚠️  跳过无效数据: {data.get('group_id', 'unknown')} - {e}")
            continue

    # 批量插入
    if point_groups:
        print(f"💾 正在插入 {len(point_groups)} 个点群...")
        await PointGroupDocument.insert_many(point_groups)
        print(f"✅ 成功导入 {len(point_groups)} 个晶体学点群")
    else:
        print("⚠️  没有数据可导入")
        return

    # 验证数据
    total = await PointGroupDocument.count()
    crystallographic = await PointGroupDocument.find(PointGroupDocument.is_crystallographic == True).count()  # noqa: E712

    print("\n📊 统计信息:")
    print(f"   - 数据库中共有 {total} 个点群")
    print(f"   - 其中 {crystallographic} 个晶体点群")

    # 显示导入的点群列表
    print("\n📋 导入的点群列表:")
    groups = await PointGroupDocument.find().sort("+order").to_list()
    for group in groups:
        crystal_system = group.crystal_system if group.crystal_system else "N/A"
        # order 现在可以是 int 或 str（如 "n", "2n"）
        order_str = str(group.order).rjust(3) if isinstance(group.order, int) else group.order
        print(f"   - {group.group_id:15s} ({group.schoenflies:6s}): order={order_str}, crystal_system={crystal_system}")


if __name__ == "__main__":
    asyncio.run(import_point_groups())
